import QtQuick 2.3
import QtQuick.LocalStorage 2.0
import fan.qt.complex 1.0 as Lex
QtObject {
    property var contentArea: null
    property int barHeight: 0
    property int barWidth: 0
    property var path: ({})
    signal submited()
    signal searched(string text)

    property bool menuVisible: false
    property url menuIconSource: ""



    property var version: QtObject{
        function checkVersion()
        {
            if (!__version__.active()) {
                __version__.open(__url__);
            }
        }

        function checked(manual)
        {
            var svn = Qt.application.version.split('.').pop();

            var data = {"svn": parseInt(svn), "platform": Qt.platform.os}

            if (manual) {
                dialog.task("正在检查版本信息");
                network.request("/version/checked",  data,  function(v){
                    response(v);
                })
            }
            else
            {
                __version__.post("/version/checked", data);
            }
        }

        function response(v){
            var svn = Qt.application.version.split('.').pop();

            if (parseInt(v.Svn) > parseInt(svn)) {
                var text = "最新版本："
                        + v.Version
                        + "（大小："
                        + (parseInt(v.Size) / 1024.0 / 1024).toFixed(1) + "MB)"
                        + " 已经发布，建议升级使用!"
                        +   v.Description;

                dialog.message("发现新版本", text, ['升级', '取消'], function(index){
                    if (index == 0) {
                        complex.delayRun(600,  download, v)
                    }
                });
            }
        }

        function download(v)
        {
            __http__.url = v.Url;
            var prefix = ".exe";
            if (Qt.platform.os == "android"){
                prefix = "apk";
            }
            else if (Qt.platform.os == "ios") {
                prefix = "ipa";
            }

            __http__.size = v.Size;

            __http__.fileName = Path.storage + "/" + v.Svn +"/" + Qt.platform.os + prefix;

            console.log("organization" + Qt.application.organization)
            console.log("version:" +  __http__.fileName)
            Path.mkpath(Path.storage + "/" + v.Svn);

            dialog.task('正在下载升级包......', function(){
                complex.updateVersion(__http__.fileName);
            });

            __http__.download();
        }

    }

    property bool initialize: false

    property var db:  QtObject{
        id: o1
        property var __db
        property string version: Qt.application.version.split('.').pop()

        function open(name)
        {
            try {
                __db =  LocalStorage.openDatabaseSync(name,
                                                      "",
                                                      Qt.application.name,
                                                      1000000);
            } catch(e) {
                console.log(JSON.stringify(e));
            }
        }

        function changeVersion(tx) {
            console.info("db version:" + __db.version);
            if (__db.version === "") {
                __db.changeVersion(__db.version, o1.version);
            }
            else {
                var temp = o1.version;
                o1.version = __db.version;
                __db.changeVersion(__db.version, temp, tx);
            }
        }

        function combine(array){
            var combined = {};
            array.forEach(function(v) {
                var keys = Object.keys(v);
                keys.forEach(function(k){
                    combined[k] = v[k];
                });
            });
            return combined;
        }

        function keys(object) {
            var ks = Object.keys(object);

            ks.sort();

            return ks;
        }

        function values(object) {
            var vs = [];
            var ks = o1.keys(object);

            ks.forEach(function(k){
                vs.push(object[k]);
            });

            return vs;
        }

        function positional(num) {
            var pos = [];
            for (var i = 0; i < num; i++) {
                pos.push("?");
            }
            return pos;
        }

        function binding(object) {
            var ks = Object.keys(object);

            ks.sort();

            var result = [];

            for (var i = 0; i < ks.length; i++) {
                result.push(ks[i] + " = ?");
            }

            return result;
        }

        function create(tableName, fields, pk)
        {
            var sql = "CREATE TABLE IF NOT EXISTS %1(%2, [CREATEDDATETIME] TEXT," +"PRIMARY KEY (%3) )"

            __db.transaction(function(tx) {tx.executeSql(sql.arg(tableName).arg(fields).arg(pk));});
        }

        function tableData(data)
        {
            return  {
                id: data._id,
                deleted: data.deleted,
                created_datetime: data.created_datetime,
                modified_datetime: data.modified_datetime
            }
        }

        function exist(table, condition)  {
            var c = false;
            __db.transaction(function(tx) {
                var rs = tx.executeSql("select count(*) as c from %1 where %2".arg(table).arg(condition));
                c = rs.rows.item(0).c > 0;
            });
            return c;
        }

        function select(sql, bind, model, attach)  {
            if (!attach) { attach = {}}
            if (!bind) { bind = []}
            __db.transaction(function(tx) {
                var rs = tx.executeSql(sql, bind);
                for(var i = 0; i < rs.rows.length; i++)
                {
                    var data = rs.rows.item(i);
                    var result = o1.combine([attach, data]);
                    model.append(result);
                }
            })
        }

        function exec(sql, callback)  {
            __db.transaction(function(tx) {
                var rs = tx.executeSql(sql);
                for(var i = 0; i < rs.rows.length; i++)
                {
                    var data = rs.rows.item(i);
                    if (callback instanceof Function) {
                        callback(data, i, rs.rows.length);
                    }
                }
            });
        }
        function transaction(sql, bind)
        {
            var record;
            if (!bind) { bind = []}
            __db.transaction(function(tx) {
                record = tx.executeSql(sql, bind);
            });
            return record;
        }

        function insert(table, object)  {
            if (!object.created_datetime)
                object.created_datetime = Qt.formatDateTime(new Date(), 'yyyy-MM-dd hh:mm:ss');
            if (!object.modified_datetime)
                object.modified_datetime = Qt.formatDateTime(new Date(), 'yyyy-MM-dd hh:mm:ss');

            var keys = o1.keys(object);
            var values = o1.values(object);
            var pos = o1.positional(keys.length);
            var sql = "INSERT INTO %1 (%2) VALUES(%3)".arg(table).arg(keys).arg(pos)
            __db.transaction(function(tx) {
                tx.executeSql(sql, values);
            });
        }
        function update(table, object, condition)  {
            if (!object.modified_datetime)
                object.modified_datetime = Qt.formatDateTime(new Date(), 'yyyy-MM-dd hh:mm:ss');
            var values = o1.values(object);
            var binds = o1.binding(object);
            var sql = "UPDATE %1 SET %2 WHERE %3".arg(table).arg(binds).arg(condition)
            __db.transaction(function(tx) {
                tx.executeSql(sql, values);
            });
        }

        function lastModified(table, field) {
            var time;
            if (!field) { field = 'modified_datetime';  }

            __db.transaction(function(tx) {
                var rs = tx.executeSql("select MAX(%1) as mdm from %2".arg(field).arg(table));
                if (rs.rows.length > 0) {
                    time = rs.rows.item(0).mdm;
                }
            });

            return time;
        }
        function replace(table, object)  {
            if (!object.created_datetime)
                object.created_datetime = Qt.formatDateTime(new Date(), 'yyyy-MM-dd hh:mm:ss');
            if (!object.modified_datetime)
                object.modified_datetime = Qt.formatDateTime(new Date(), 'yyyy-MM-dd hh:mm:ss');
            var keys = o1.keys(object);
            var values = o1.values(object);
            var pos = o1.positional(keys.length);
            var sql = 'INSERT OR REPLACE INTO %1 (%2) VALUES(%3)'.arg(table).arg(keys).arg(pos);

            __db.transaction(function(tx) {
                tx.executeSql(sql, values);
            });
        }

        function del(table, condition, bind)  {
            if (!bind) { bind = []};
            var sql = "DELETE FROM %1 WHERE %2".arg(table).arg(condition);
            __db.transaction(function(tx) {
                tx.executeSql(sql, bind);
            });
        }
    }

    property var io:  QtObject{
        id: o4
        function write(fileName, data){__api__.writeText(fileName, data)}
        function read(fileName){return __api__.readText(fileName, "UTF-8")}

        function isImage(url) {__api__.isImage(url)}
        function mkpath(p) { return __api__.mkpath(p)}

        function exists(p) {return __api__.pathExist(p)}

        function toUrlPath(filePath) {
            return __api__.toUrl(filePath);
        }
        function toLocalFile(url) {
            return __api__.toLocalFile(url);
        }

        function fileList(path) {
            return __api__.files(path);
        }
        function remove(fileName){return __api__.removeFile(fileName)}

        function folder(filePath) {return __api__.folder(filePath)}
    }

    property var crypto:  QtObject{
        id: o5
        function encrypt(key, data){ return __api__.encrypt(key, data)
        }
        function decrypt(key, data){ return __api__.decrypt(key, data)
        }

        function isBase64(data)
        {
            var exp = /^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$/;
            return exp.test(data);
        }
        function toBase64(url, size) {
            return __api__.toBase64(url, size);
        }
        function fileImageBase64(fileName, size){return __api__.__imageFileBase64(fileName, size)}

        function newGUID()
        {
            return __api__.newGUID();
        }
        function zeroFill(num, fieldWidth) {
            return __api__.zeroFill(num, fieldWidth);
        }
        function toDateTime(datetime, format)
        {
            return __api__.toDateTime(datetime, format);
        }
    }

    property var config:  QtObject{
        id: __config
        property bool authorize: false
        property string name: ""
        property string b1: ""
        property string b2: ""
        property string c1: ""
        property string c2: ""
        property string uid: ""
        property string key: ""
        property string password: ""
        property bool authentication: false
        //property string token
        signal clicked()

        property var license: ({})
        property bool registered: true
        property bool recovered: true
        //property int toolBarHeight: iHEIGHT
        //property string organization: Qt.application.organization
        //property int svn: Qt.application.version.split('.').pop()

        property var complex: ({})

        property bool interactive: false



        function saveRes(){
            var pconf = object.storage +"/config.dat";
            var res = JSON.stringify(localRes)

            console.info("#save res:", res)

            io.write(pconf, crypto.encrypt(object.key, res));
        }

        function loadRes(){
            var pconf = object.storage +"/config.dat";
            if (io.exists(pconf)){
                var data = io.read(pconf);

                var res = crypto.decrypt(object.key, data);

                console.info("#load res:", res)

                localRes = JSON.parse(res)
            }
            return null;
        }

        function logSupported()
        {
            db.open(Qt.application.name);

            db.create("TFX_LOG", "[ID] TEXT, [LEVEL] TEXT, [FILE] TEXT, [LINE] INTEGER, [FUNCTION] TEXT, [MESSAGE] TEXT", 'ID');
        }

        function logToDB(message)
        {
            message.ID = crypto.newGUID();

            db.transaction("INSERT INTO TFX_LOG ([ID], [LEVEL], [FILE], [LINE], [FUNCTION], [MESSAGE]) VALUES(？)", message)
        }

        function selectLanguage(index){__translation__.selectLanguage(index)}
        function supportedLanguage(){
            return __translation__.supportedLanguage();
        }
    }

    property var dialog: QtObject {
        id: o7


        function message(text)
        {
              var component = Qt.createComponent(Qt.resolvedUrl("../template/MessageText.qml"), util.contentArea);

            if (component.status === Component.Ready) {
                var i = component.createObject(contentArea,  {"text": text});
                i.open()
            }
            else {
                console.error("create component error: " + component.errorString());
            }

        }

        function toast(text)
        {
            var component = Qt.createComponent(Qt.resolvedUrl("../template/Toast.qml"), util.contentArea);

          if (component.status === Component.Ready) {
              var i = component.createObject(contentArea,  {"text": text});
              i.open()
          }
          else {
              console.error("create component error: " + component.errorString());
          }


        }

    }




    property var url: QtObject{
        id: o15

        function isValid(u) {
            return __api__.isValid(u);
        }
    }


    function mapToGlobal(pos) {
        return __api__.mapToGlobal(window, pos)
    }
    function mapToWindow(item, pos) {
        var p = item.mapToItem(util.contentArea, pos.x, pos.y)
        return Qt.point(p.x, p.y + util.barHeight)
    }
    function adsorption(pos) {
        __api__.setCurror(pos)
    }
    function contains(rect, x, y) {
        return __api__.contains(rect, x, y)
    }

    property var complex:  QtObject{
        id: __complex

        function textToClipboard(text) {
            __api__.textToClipboard(text);
        }
        function imageToClipboard(image)
        {
            __api__.imageToClipboard(image);
        }



        function isSupportedImage(fileName) {return __api__.__isSupportedImage(fileName);}

        function updateVersion(fileName)
        {
            __api__.updateVersion(fileName);
        }


        function clearMenuItem(menu) {
            while (menu && menu.contentModel.count) {
                menu.removeItem(0)
            }
        }


    }


}

